package com.qixin.activiti;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qixin.modules.eaBasic.entity.EaTask;
import com.qixin.modules.eaBasic.mapper.EaTaskMapper;
import com.qixin.modules.eaBasic.vo.IdVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import com.qixin.activiti.api.IActivitiService;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricIdentityLink;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.image.ProcessDiagramGenerator;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.util.EmptyUtil;
import org.jeecg.modules.activiti.entity.ActBusiness;
import org.jeecg.modules.activiti.entity.ActivitiConstant;
import org.jeecg.modules.activiti.entity.Assignee;
import org.jeecg.modules.activiti.entity.HistoricTaskVo;
import org.jeecg.modules.activiti.mapper.ActEaTaskMapper;
import org.jeecg.modules.activiti.service.Impl.ActBusinessServiceImpl;
import org.jeecg.modules.system.vo.ActivitiCancelVo;
import org.jeecg.modules.system.vo.ActivitiVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import sun.misc.BASE64Encoder;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author:wly
 * @Date:2021/10/19
 * @Describtion: 工作流访问层
 */
@Api(tags="app工作流类")
@Slf4j
@RestController
@RequestMapping("/system/activiti")
public class ApiController {
    @Autowired
    private IActivitiService iActivitiService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    ISysBaseAPI sysBaseAPI;
    @Autowired
    private ActBusinessServiceImpl actBusinessService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private EaTaskMapper eaTaskMapper;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private ProcessEngineConfiguration processEngineConfiguration;
    @Value(value = "${server.fileurl}")
    private String fileurl;
    @Value(value = "${jeecg.path.upload}")
    private String uploadpath;
    @Autowired
    private ActEaTaskMapper actEaTaskMapper;

    /**
     * @Description: 保存发起工作流程
     * @author: wly
     * @date: 2021/7/22 11:22
     * @param activitiVo
     */
    @AutoLog(value = "保存发起工作流程")
    @ApiOperation(value="保存发起工作流程", notes="保存发起工作流程")
    @RequestMapping(value = "/addActivitiApply", method = RequestMethod.POST)
    public void addActivitiApply(@RequestBody ActivitiVo activitiVo) {
        iActivitiService.addActivitiApply(activitiVo,false);
    }

    /**
     * @Description: 提交发起工作流程
     * @author: wly
     * @date: 2021/7/22 11:22
     * @param activitiVo
     */
    @AutoLog(value = "提交发起工作流程")
    @ApiOperation(value="提交发起工作流程", notes="提交发起工作流程")
    @RequestMapping(value = "/sendActivitiApply", method = RequestMethod.POST)
    public void sendActivitiApply(@RequestBody ActivitiVo activitiVo) {
        iActivitiService.sendActivitiApply(activitiVo,false);
    }

    /**
     * @Description: 流程审批
     * @author: wly
     * @date: 2021/7/22 11:22
     * @param activitiVo
     */
    @AutoLog(value = "流程审批")
    @ApiOperation(value="流程审批", notes="流程审批")
    @RequestMapping(value = "/pass", method = RequestMethod.POST)
    public Result<?> pass(@RequestBody ActivitiVo activitiVo) {
        //eaTask,单据涉及到的表名(如差旅费报销单ea_travel)
        Map<String,Object> taskParams = new HashMap<String,Object>();
        taskParams.put("form_id",activitiVo.getId());
        List<EaTask> eaTaskList  = eaTaskMapper.selectByMap(taskParams);
        EaTask eaTask = new EaTask();
        if(eaTaskList.size() > 0){
            eaTask = eaTaskList.get(0);
        }

        String status = EmptyUtil.checkNull(eaTask.getStatus());   //状态
        if(status.equals("2")){  //已审核
            return Result.error("单据已审核,请刷新待办列表");
        }

        //判断单据是否已经被变更
        /*String taskId = EmptyUtil.checkNull(activitiVo.getTaskId());    //待办任务id
        Map<String,Object> actRuTaskMap = actEaTaskMapper.selectActRuTask(taskId);
        if(actRuTaskMap == null){
            throw new RuntimeException("该待办已被处理,请刷新待办列表");
        }*/

        String updateTime = EmptyUtil.checkNull(activitiVo.getTime());   //更新时间
        String msg = iActivitiService.checkFormChange(updateTime,eaTask.getFormType(),eaTask.getFormId());
        if(!msg.equals("")){
            return Result.error(msg + "待办列表");
        }

        String msg2 = iActivitiService.pass(activitiVo,eaTask);
        if(msg2.equals("")){
            return Result.OK("审批成功");
        }else{
            Map<String,Object> returnMap = new HashMap<String,Object>();
            returnMap.put("flash",1);   //页面刷新:1刷新
            return Result.error(returnMap,msg);
        }
    }

    /**
     * @Description: 流程驳回
     * @author: wly
     * @date: 2021/7/22 11:22
     * @param activitiVo
     */
    @AutoLog(value = "流程驳回")
    @ApiOperation(value="流程驳回", notes="流程驳回")
    @RequestMapping(value = "/back", method = RequestMethod.POST)
    public Result<?> back(@RequestBody ActivitiVo activitiVo) {
        //eaTask,单据涉及到的表名(如差旅费报销单ea_travel)
        Map<String,Object> taskParams = new HashMap<String,Object>();
        taskParams.put("form_id",activitiVo.getId());
        List<EaTask> eaTaskList  = eaTaskMapper.selectByMap(taskParams);
        EaTask eaTask = new EaTask();
        if(eaTaskList.size() > 0){
            eaTask = eaTaskList.get(0);
        }

        String status = EmptyUtil.checkNull(eaTask.getStatus());   //状态
        if(status.equals("2")){  //已审核
            return Result.error("单据已审核,请刷新待办列表");
        }

        //判断单据是否已经被变更
        /*String taskId = EmptyUtil.checkNull(activitiVo.getTaskId());    //待办任务id
        Map<String,Object> actRuTaskMap = actEaTaskMapper.selectActRuTask(taskId);
        if(actRuTaskMap == null){
            throw new RuntimeException("该待办已被处理,请刷新待办列表");
        }*/

        String updateTime = EmptyUtil.checkNull(activitiVo.getTime());   //更新时间
        String msg = iActivitiService.checkFormChange(updateTime,eaTask.getFormType(),eaTask.getFormId());
        if(!msg.equals("")){
            return Result.error(msg + "待办列表");
        }

        String msg2 = iActivitiService.back(activitiVo,eaTask);
        if(msg2.equals("")){
            return Result.OK("驳回成功");
        }else{
            Map<String,Object> returnMap = new HashMap<String,Object>();
            returnMap.put("flash",1);   //页面刷新:1刷新
            return Result.error(returnMap,msg);
        }
    }

    /**
     * @Description: 流程撤回
     * @author: wly
     * @date: 2021/7/22 11:22
     * @param activitiCancelVo
     */
    @AutoLog(value = "流程撤回")
    @ApiOperation(value="流程撤回", notes="流程撤回")
    @RequestMapping(value = "/cancel", method = RequestMethod.POST)
    public Result<?> cancel(@RequestBody ActivitiCancelVo activitiCancelVo) {
        //eaTask,单据涉及到的表名(如差旅费报销单ea_travel)
        Map<String,Object> taskParams = new HashMap<String,Object>();
        taskParams.put("form_id",activitiCancelVo.getId());
        List<EaTask> eaTaskList  = eaTaskMapper.selectByMap(taskParams);
        EaTask eaTask = new EaTask();
        if(eaTaskList.size() > 0){
            eaTask = eaTaskList.get(0);
        }

        String status = EmptyUtil.checkNull(eaTask.getStatus());   //单据状态
        if(status.equals("2")){  //已审批
            return Result.error("单据已审批不允许撤销");
        }

        //判断单据是否已经被变更
        /*String updateTime = EmptyUtil.checkNull(activitiCancelVo.getUpdateTime());   //更新时间
        String msg = checkFormChange(updateTime,eaTask.getFormType(),eaTask.getFormId());
        if(!msg.equals("")){
            return Result.error(msg + "已办列表");
        }else{

        }*/
        String taskId2 = EmptyUtil.checkNull(activitiCancelVo.getTaskId());    //已办任务id
        Map<String,Object> actHiActinst2 = actEaTaskMapper.selectActHiActinst(taskId2);
        String startTime2 = "";
        String procInstId2 = "";
        if(actHiActinst2 == null){
            return Result.error("单据状态已变更,请刷新已办列表");
        }else{
            startTime2 = EmptyUtil.checkNull(actHiActinst2.get("START_TIME_"));   //开始时间
            procInstId2 = EmptyUtil.checkNull(actHiActinst2.get("PROC_INST_ID_"));   //流程id
        }

        List<Map<String,Object>> actHiTaskList2 = actEaTaskMapper.selectActHiTaskFromTime(startTime2,procInstId2);
        if(actHiTaskList2 == null || actHiTaskList2.size() == 0 || actHiTaskList2.size() > 1){
            return Result.error("单据状态已变更,请刷新已办列表");
        }

        String msg = iActivitiService.cancel(activitiCancelVo,eaTask);
        if(msg.equals("")){
            return Result.OK("撤回成功");
        }else{
            Map<String,Object> returnMap = new HashMap<String,Object>();
            returnMap.put("flash",1);   //页面刷新:1刷新
            return Result.error(returnMap,msg);
        }
    }

    /*流程流转历史-procInstId*/
    @AutoLog(value = "流程-流程流转历史-procInstId")
    @ApiOperation(value="流程-流程流转历史-procInstId", notes="流程流转历史-procInstId")
    @RequestMapping(value = "/historicFlow", method = RequestMethod.POST)
    public Result<Object> historicFlow(@RequestBody IdVo idVo){

        List<HistoricTaskVo> list = new ArrayList<>();

        List<HistoricTaskInstance> taskList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(idVo.getId()).orderByHistoricTaskInstanceStartTime().desc().list();

        // 转换vo
        taskList.forEach(e -> {
            HistoricTaskVo htv = new HistoricTaskVo(e);
            List<Assignee> assignees = new ArrayList<>();
            // 关联分配人（委托用户时显示该人）
            if(StrUtil.isNotBlank(htv.getAssignee())){
                String assignee = sysBaseAPI.getUserById(htv.getAssignee()).getRealname();
                String owner = sysBaseAPI.getUserById(htv.getOwner()).getRealname();
                assignees.add(new Assignee(assignee+"(受"+owner+"委托)", true));
            }
            List<HistoricIdentityLink> identityLinks = historyService.getHistoricIdentityLinksForTask(e.getId());
            // 获取实际审批用户id
            List<String> userIds_b = actBusinessService.findUserIdByTypeAndTaskId(ActivitiConstant.EXECUTOR_TYPE_b, e.getId());
            List<String> userIds_p = actBusinessService.findUserIdByTypeAndTaskId(ActivitiConstant.EXECUTOR_TYPE_p, e.getId());
            for(HistoricIdentityLink hik : identityLinks){
                // 关联候选用户（分配的候选用户审批人）
                if(ActivitiConstant.EXECUTOR_candidate.equals(hik.getType())&& StrUtil.isNotBlank(hik.getUserId())){
                    String username = sysBaseAPI.getUserById(hik.getUserId()).getRealname();
                    Assignee assignee = new Assignee(username, false);
                    /*审批过的标记一下，前端标颜色用*/
                    if(CollectionUtil.contains(userIds_b,hik.getUserId()) || CollectionUtil.contains(userIds_p,hik.getUserId())){
                        assignee.setIsExecutor(true);
                    }
                    assignees.add(assignee);
                }
            }
            htv.setAssignees(assignees);
            // 关联审批意见
            List<Comment> comments = taskService.getTaskComments(htv.getId(), "comment");
            if(comments!=null&&comments.size()>0){
                htv.setComment(comments.get(0).getFullMessage());
            }

            //如果deletereason为审批通过,同时
            String deleteReason = EmptyUtil.checkNull(htv.getDeleteReason());
            String name = EmptyUtil.checkNull(htv.getName());
            if(name.equals("用户提交") && deleteReason.equals("审批通过")){
                htv.setDeleteReason("提交审批");
            }

            list.add(htv);
        });
        return Result.ok(list);
    }

    /*流程流转历史-formId*/
    @AutoLog(value = "流程-流程流转历史-formId")
    @ApiOperation(value="流程-流程流转历史-formId", notes="流程流转历史-formId")
    @RequestMapping(value = "/historicFlowByFormId", method = RequestMethod.POST)
    public Result<Object> historicFlowByFormId(@RequestBody IdVo idVo){
        List<HistoricTaskVo> list = new ArrayList<>();
        String formId = idVo.getId();   //单据id
        Map params = new HashMap();
        params.put("form_id",formId);
        List<EaTask> eaTasks = eaTaskMapper.selectByMap(params);   //任务表,获取procInstId

        String procInstId = EmptyUtil.checkNull(eaTasks.get(0).getProcinstId());   //流程id
        if(procInstId.equals("")){
            return Result.error("流程id为空");
        }

        List<HistoricTaskInstance> taskList = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(procInstId).orderByHistoricTaskInstanceStartTime().desc().list();

        // 转换vo
        taskList.forEach(e -> {
            HistoricTaskVo htv = new HistoricTaskVo(e);
            List<Assignee> assignees = new ArrayList<>();
            // 关联分配人（委托用户时显示该人）
            if(StrUtil.isNotBlank(htv.getAssignee())){
                String assignee = sysBaseAPI.getUserById(htv.getAssignee()).getRealname();
                String owner = sysBaseAPI.getUserById(htv.getOwner()).getRealname();
                assignees.add(new Assignee(assignee+"(受"+owner+"委托)", true));
            }
            List<HistoricIdentityLink> identityLinks = historyService.getHistoricIdentityLinksForTask(e.getId());
            // 获取实际审批用户id
            List<String> userIds_b = actBusinessService.findUserIdByTypeAndTaskId(ActivitiConstant.EXECUTOR_TYPE_b, e.getId());
            List<String> userIds_p = actBusinessService.findUserIdByTypeAndTaskId(ActivitiConstant.EXECUTOR_TYPE_p, e.getId());
            for(HistoricIdentityLink hik : identityLinks){
                // 关联候选用户（分配的候选用户审批人）
                if(ActivitiConstant.EXECUTOR_candidate.equals(hik.getType())&& StrUtil.isNotBlank(hik.getUserId())){
                    String username = sysBaseAPI.getUserById(hik.getUserId()).getRealname();
                    Assignee assignee = new Assignee(username, false);
                    /*审批过的标记一下，前端标颜色用*/
                    if(CollectionUtil.contains(userIds_b,hik.getUserId()) || CollectionUtil.contains(userIds_p,hik.getUserId())){
                        assignee.setIsExecutor(true);
                    }
                    assignees.add(assignee);
                }
            }
            htv.setAssignees(assignees);
            // 关联审批意见
            List<Comment> comments = taskService.getTaskComments(htv.getId(), "comment");
            if(comments!=null&&comments.size()>0){
                htv.setComment(comments.get(0).getFullMessage());
            }

            //如果deletereason为审批通过,同时
            String deleteReason = EmptyUtil.checkNull(htv.getDeleteReason());
            String name = EmptyUtil.checkNull(htv.getName());
            if(name.equals("用户提交") && deleteReason.equals("审批通过")){
                htv.setDeleteReason("提交审批");
            }

            list.add(htv);
        });
        return Result.ok(list);
    }

    /*获取高亮实时流程图-procInstId*/
    @AutoLog(value = "获取高亮实时流程图-procInstId")
    @ApiOperation(value="获取高亮实时流程图-procInstId", notes="获取高亮实时流程图-procInstId")
    @RequestMapping(value = "/getHighlightImg", method = RequestMethod.POST)
    public Result<?> getHighlightImg(@RequestBody IdVo idVo, HttpServletResponse response){
        String id = idVo.getId();     //流程id
        InputStream inputStream = null;
        ProcessInstance pi = null;
        String picName = id + ".png";
        // 查询历史
        HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(id).singleResult();
        if (hpi.getEndTime() != null) {
            // 已经结束流程获取原图
            ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(hpi.getProcessDefinitionId()).singleResult();
            //picName = pd.getDiagramResourceName();
            inputStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), pd.getDiagramResourceName());
        } else {
            pi = runtimeService.createProcessInstanceQuery().processInstanceId(id).singleResult();
            BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());

            List<String> highLightedActivities = new ArrayList<String>();
            // 高亮任务节点
            List<Task> tasks = taskService.createTaskQuery().processInstanceId(id).list();
            for (Task task : tasks) {
                highLightedActivities.add(task.getTaskDefinitionKey());
            }

            List<String> highLightedFlows = new ArrayList<String>();
            ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
            //"宋体"
            inputStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivities, highLightedFlows,
                    "宋体", "宋体", "宋体",null, 1.0);
            //picName = pi.getName()+".png";
        }

        String base64 = convertFileToBase64(inputStream);
        Map<String,Object> returnMap = new HashMap<String,Object>();
        returnMap.put("url",base64);
        return Result.OK(returnMap);

        /*String fileName = uploadpath + "/procInst/" + id + ".png";

        //如果文件夹不存在,先新建
        File file = new File(fileName);
        file.delete();
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }

        try {
            int index;
            byte[] bytes = new byte[1024];
            FileOutputStream downloadFile = new FileOutputStream(fileName);
            while ((index = inputStream.read(bytes)) != -1) {
                downloadFile.write(bytes, 0, index);
                downloadFile.flush();
            }
            inputStream.close();
            downloadFile.close();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            Map<String,Object> returnMap = new HashMap<String,Object>();
            returnMap.put("url",fileName.replace(uploadpath,fileurl));
            return Result.OK(returnMap);
        }*/

        /*try {
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(picName, "UTF-8"));
            byte[] b = new byte[1024];
            int len = -1;
            while ((len = inputStream.read(b, 0, 1024)) != -1) {
                response.getOutputStream().write(b, 0, len);
            }
            response.flushBuffer();
        } catch (IOException e) {
            log.error(e.toString());
            throw new JeecgBootException("读取流程图片失败");
        }*/
    }

    /*获取高亮实时流程图-formId*/
    @AutoLog(value = "获取高亮实时流程图-formId")
    @ApiOperation(value="获取高亮实时流程图-formId", notes="获取高亮实时流程图-formId")
    @RequestMapping(value = "/getHighlightImgByFormId", method = RequestMethod.POST)
    public Result<?> getHighlightImgByFormId(@RequestBody IdVo idVo, HttpServletResponse response){
        String formId = idVo.getId();   //单据id
        Map params = new HashMap();
        params.put("form_id",formId);
        List<EaTask> eaTasks = eaTaskMapper.selectByMap(params);   //任务表,获取procInstId

        InputStream inputStream = null;
        ProcessInstance pi = null;
        String picName = eaTasks.get(0).getProcinstId() + ".png";
        // 查询历史
        HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery().processInstanceId(eaTasks.get(0).getProcinstId()).singleResult();
        if (hpi.getEndTime() != null) {
            // 已经结束流程获取原图
            ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(hpi.getProcessDefinitionId()).singleResult();
            //picName = pd.getDiagramResourceName();
            inputStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), pd.getDiagramResourceName());
        } else {
            pi = runtimeService.createProcessInstanceQuery().processInstanceId(eaTasks.get(0).getProcinstId()).singleResult();
            BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());

            List<String> highLightedActivities = new ArrayList<String>();
            // 高亮任务节点
            List<Task> tasks = taskService.createTaskQuery().processInstanceId(eaTasks.get(0).getProcinstId()).list();
            for (Task task : tasks) {
                highLightedActivities.add(task.getTaskDefinitionKey());
            }

            List<String> highLightedFlows = new ArrayList<String>();
            ProcessDiagramGenerator diagramGenerator = processEngineConfiguration.getProcessDiagramGenerator();
            //"宋体"
            inputStream = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivities, highLightedFlows,
                    "宋体", "宋体", "宋体",null, 1.0);
            //picName = pi.getName()+".png";
        }

        String base64 = convertFileToBase64(inputStream);
        Map<String,Object> returnMap = new HashMap<String,Object>();
        returnMap.put("url",base64);
        return Result.OK(returnMap);

        /*String fileName = uploadpath + "/procInst/" + eaTasks.get(0).getProcinstId() + ".png";

        //如果文件夹不存在,先新建
        File file = new File(fileName);
        file.delete();
        if(!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }

        try {
            int index;
            byte[] bytes = new byte[1024];
            FileOutputStream downloadFile = new FileOutputStream(fileName);
            while ((index = inputStream.read(bytes)) != -1) {
                downloadFile.write(bytes, 0, index);
                downloadFile.flush();
            }
            inputStream.close();
            downloadFile.close();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            Map<String,Object> returnMap = new HashMap<String,Object>();
            returnMap.put("url",fileName.replace(uploadpath,fileurl));
            return Result.OK(returnMap);
        }*/

        /*try {
            response.setContentType("application/octet-stream;charset=UTF-8");
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(picName, "UTF-8"));
            byte[] b = new byte[1024];
            int len = -1;
            while ((len = inputStream.read(b, 0, 1024)) != -1) {
                response.getOutputStream().write(b, 0, len);
            }
            response.flushBuffer();
        } catch (IOException e) {
            log.error(e.toString());
            throw new JeecgBootException("读取流程图片失败");
        }*/
    }

    /**
     * 本地文件（图片、excel等）转换成Base64字符串
     *
     * @param in
     */
    public String convertFileToBase64(InputStream in) {
        byte[] data = null;
        // 读取图片字节数组
        try {
            System.out.println("文件大小（字节）="+in.available());
            data = new byte[in.available()];
            in.read(data);
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 对字节数组进行Base64编码，得到Base64编码的字符串
        BASE64Encoder encoder = new BASE64Encoder();
        String base64Str = encoder.encode(data);
        return "data:image/png;base64," + base64Str;
    }

    /*根据单据Id获取流程实例Id*/
    @AutoLog(value = "根据单据Id获取流程实例Id")
    @ApiOperation(value="根据单据Id获取流程实例Id", notes="根据单据Id获取流程实例Id")
    @RequestMapping(value = "/getProcinstId", method = RequestMethod.POST)
    public Result<?> getProcinstId(@RequestBody IdVo idVo) {
        // update-begin-by wjb 2022-1-26
        String formId = idVo.getId();   //单据id
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("table_id",formId);
        // 通过表单id 查对应的流程实例
        List<ActBusiness> actBusinessList = actBusinessService.list(queryWrapper);

        String procinstId = "";
        if(actBusinessList.size() > 0){
            procinstId = actBusinessList.get(0).getProcInstId();
        }
        // update-end-by wjb 2022-1-26
        Map<String,Object> returnMap = new HashMap<String,Object>();
        returnMap.put("procInstId",procinstId);
        return Result.OK(returnMap);
    }

    /*根据已办任务Id确定是否当前任务是否可以被撤回*/
    @AutoLog(value = "根据已办任务Id确定是否当前任务是否可以被撤回")
    @ApiOperation(value="根据已办任务Id确定是否当前任务是否可以被撤回", notes="根据已办任务Id确定是否当前任务是否可以被撤回")
    @RequestMapping(value = "/getTaskIsCancel", method = RequestMethod.POST)
    public Result<?> getTaskIsCancel(@RequestBody ActivitiCancelVo activitiCancelVo) {
        int isCancel = iActivitiService.getTaskIsCancel(activitiCancelVo);
        Map<String,Object> returnMap = new HashMap<String,Object>();
        returnMap.put("isCancel",isCancel);
        return Result.OK(returnMap);
    }

    /**
     * @Description: 根据单据id查询最近一个已办任务id
     * @author: wly
     * @date: 2021/7/22 11:22
     * @param idVo
     */
    @AutoLog(value = "根据单据id查询最近一个已办任务id")
    @ApiOperation(value="根据单据id查询最近一个已办任务id", notes="根据单据id查询最近一个已办任务id")
    @RequestMapping(value = "/getLastHiTaskId", method = RequestMethod.POST)
    public Result<?> getLastHiTaskId(@RequestBody IdVo idVo) {
        String taskId = iActivitiService.getLastHiTaskId(idVo);
        Map<String,Object> returnMap = new HashMap<String,Object>();
        returnMap.put("taskId",taskId);
        return Result.OK(returnMap);
    }

}
